package cn.zxf.note.common.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.*;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * Created by zengxf on 2020/3/25.
 */
@Slf4j
public class RestUtils {

    public static RestTemplate build() {
        ClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        RestTemplate rest = new RestTemplate(new BufferingClientHttpRequestFactory(factory));
        rest.getInterceptors()
                .add(new LoggingClientHttpRequestInterceptor());
        return rest;
    }

    public static <T> T get(String url, Class<T> responseType, Map params) {
        RestTemplate rest = RestUtils.build();
        ResponseEntity<String> res = rest.getForEntity(url, String.class, params);
        String json = res.getBody();
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(json, responseType);
        } catch (IOException e) {
            throw new RuntimeException("请求出错", e);
        }
    }


    public static class LoggingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
        @Override
        public ClientHttpResponse intercept(
                HttpRequest request,
                byte[] body,
                ClientHttpRequestExecution execution
        ) throws IOException {
            this.traceRequest(request);
            ClientHttpResponse response = execution.execute(request, body);
            this.traceResponse(response);
            return response;
        }

        private void traceRequest(HttpRequest request) {
            log.debug("============================ request begin ================================================");
            log.debug("URI          : {}", request.getURI());
            log.debug("Method       : {}", request.getMethod());
            log.debug("============================ request end  ================================================");
        }

        private void traceResponse(ClientHttpResponse response) throws IOException {
            StringBuilder inputStringBuilder = new StringBuilder();
            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"))) {
                String line = bufferedReader.readLine();
                while (line != null) {
                    inputStringBuilder.append(line);
                    inputStringBuilder.append('\n');
                    line = bufferedReader.readLine();
                }
            }
            log.debug("============================ response begin ==========================================");
            log.debug("Status code  : {}", response.getStatusCode());
            log.debug("Headers      : {}", response.getHeaders());
            log.debug("Response body: {}", inputStringBuilder);
            log.debug("============================ response end =================================================");
        }
    }

}
